//+------------------------------------------------------------------+
//|                                            TrailingFixedPips.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert/ExpertTrailing.h>  // 移动止损基类（提供止损框架）

// wizard description start（MQL5 策略向导描述）
//+----------------------------------------------------------------------+
//| 类功能描述                                                           |
//| Title=基于固定点数的移动止损（Trailing Stop）                        |
//| Type=Trailing                                                       |
//| Name=FixedPips                                                      |
//| Class=CTrailingFixedPips                                            |
//| Page=                                                               |
//| Parameter=StopLevel,int,30,止损点数（固定移动止损的触发阈值，单位：点） |
//| Parameter=ProfitLevel,int,50,止盈点数（固定移动止盈的触发阈值，单位：点）|
//+----------------------------------------------------------------------+
// wizard description end

//+------------------------------------------------------------------+
//| CTrailingFixedPips 类：基于固定点数的移动止损实现                    |
//| 核心功能：继承自 CExpertTrailing，通过设置固定点数的止损/止盈阈值，   |
//|           在价格向有利方向移动达到阈值时，自动调整止损位跟随价格移动， |
//|           锁定已有利润并限制潜在亏损，适用于趋势跟踪策略              |
//| 核心逻辑：当盈利超过设定点数时，将止损位调整为当前价格减去固定点数（多单） |
//|           或当前价格加上固定点数（空单），实现止损随盈利自动上移/下移   |
//+------------------------------------------------------------------+
class CTrailingFixedPips : public CExpertTrailing
  {
protected:
   // 核心参数（保护成员，子类可访问）
   int               m_stop_level;     // 止损点数阈值（触发移动止损的最小点数，单位：点）
   int               m_profit_level;   // 止盈点数阈值（触发移动止盈的最小点数，单位：点）

public:
   //----------------------------------------------------------------
   // 构造与析构函数
   //----------------------------------------------------------------
   /**
    * @brief 构造函数：初始化固定点数移动止损参数
    * @details 1. 设置默认止损点数=30点，止盈点数=50点（适配多数短线策略）；
    *          2. 继承父类 CExpertTrailing 的移动止损框架初始化
    */
                     CTrailingFixedPips(void);

   /**
    * @brief 析构函数：清理固定点数移动止损资源
    * @details 释放参数占用的内存，依赖父类析构逻辑完成止损框架资源清理
    */
                    ~CTrailingFixedPips(void);

   //----------------------------------------------------------------
   // 参数配置：修改止损/止盈点数（外部调用接口）
   //----------------------------------------------------------------
   /**
    * @brief 设置移动止损的触发阈值（点数）
    * @param stop_level [in] 止损点数（需≥0，且满足平台最小止损要求，如多数平台≥10点）
    */
   void              StopLevel(int stop_level);

   /**
    * @brief 设置移动止盈的触发阈值（点数）
    * @param profit_level [in] 止盈点数（0=不启用移动止盈，>0时需满足平台最小止损要求）
    */
   void              ProfitLevel(int profit_level);

   //----------------------------------------------------------------
   // 参数验证：确保止损/止盈设置符合平台规则（移动止损生效前提）
   //----------------------------------------------------------------
   /**
    * @brief 验证止损/止盈参数的有效性
    * @return bool - 验证结果：true=参数有效，false=参数无效（如小于平台最小止损）
    * @note 验证逻辑：
    *       1. 先调用父类 ValidationSettings() 验证基础框架参数；
    *       2. 检查止损点数（m_stop_level）：若>0，需≥当前品种的最小止损点数（m_symbol.StopsLevel()）；
    *       3. 检查止盈点数（m_profit_level）：若>0，需≥当前品种的最小止损点数；
    *       4. 若不满足，输出错误日志并返回false
    */
   virtual bool      ValidationSettings(void);

   //----------------------------------------------------------------
   // 移动止损核心逻辑：分别处理多单和空单的止损调整
   //----------------------------------------------------------------
   /**
    * @brief 检查多单（买入）的移动止损/止盈条件，计算新止损位
    * @param position [in] 持仓信息对象（包含开仓价、当前止损等数据）
    * @param sl [out] 新止损价（若满足条件则更新，否则为EMPTY_VALUE）
    * @param tp [out] 新止盈价（若启用移动止盈且满足条件则更新，否则为EMPTY_VALUE）
    * @return bool - 调整结果：true=已更新止损/止盈，false=未调整
    * @note 多单逻辑：
    *       1. 基准价=初始止损价（若未设置则用开仓价）；
    *       2. 当前价格（卖价 Bid）与基准价的差>止损点数×点值 → 触发移动止损；
    *       3. 新止损价=当前 Bid 价 - 止损点数×点值；
    *       4. 若启用止盈（m_profit_level>0），新止盈价=当前 Bid 价 + 止盈点数×点值
    */
   virtual bool      CheckTrailingStopLong(CPositionInfo *position,double &sl,double &tp);

   /**
    * @brief 检查空单（卖出）的移动止损/止盈条件，计算新止损位
    * @param position [in] 持仓信息对象（包含开仓价、当前止损等数据）
    * @param sl [out] 新止损价（若满足条件则更新，否则为EMPTY_VALUE）
    * @param tp [out] 新止盈价（若启用移动止盈且满足条件则更新，否则为EMPTY_VALUE）
    * @return bool - 调整结果：true=已更新止损/止盈，false=未调整
    * @note 空单逻辑：
    *       1. 基准价=初始止损价（若未设置则用开仓价）；
    *       2. 基准价与当前价格（买价 Ask）的差>止损点数×点值 → 触发移动止损；
    *       3. 新止损价=当前 Ask 价 + 止损点数×点值；
    *       4. 若启用止盈（m_profit_level>0），新止盈价=当前 Ask 价 - 止盈点数×点值
    */
   virtual bool      CheckTrailingStopShort(CPositionInfo *position,double &sl,double &tp);
  };
//+------------------------------------------------------------------+